home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 014 / libtools.arc / VDSK2-0.AQM / VDSK2-0.ASM
Encoding:
Assembly Source File  |  1984-04-08  |  11.0 KB  |  389 lines

  1.     PAGE    66,132
  2. ;
  3. ;    ********************************************r*l*b**
  4. ;    *          PROLOG              *
  5. ;    *  THIS IS AN  DEVICE DRIVER FOR AN IN STORAGE      *
  6. ;    *  DISKETTE (VIRTUAL) WITH 180K CAPACITY.      *
  7. ;    ********************************************r*l*b**
  8. CSEG    SEGMENT PARA PUBLIC 'CODE'
  9. ;
  10. ;    M A C R O ( S )
  11. ;
  12. STATUS    MACRO    STATE,ERR,RC
  13.     IFIDN    <STATE>,<DONE>
  14.      OR    ES:WORD PTR SRH_STA_FLD[BX],0100H
  15.     ENDIF
  16.     IFIDN    <STATE>,<BUSY>
  17.      OR    ES:WORD PTR SRH_STA_FLD[BX],0200H
  18.     ENDIF
  19.     IFIDN    <ERR>,<ERROR>
  20.      OR    ES:WORD PTR SRH_STA_FLD[BX],0100H
  21.     ENDIF
  22.     IFNB    <RC>
  23.      OR    ES:WORD PTR SRH_STA_FLD[BX],RC
  24.     ENDIF
  25.     ENDM
  26. ;
  27. ;    E Q U A T E S
  28. ;
  29. ;  READ/WRITE
  30. ;
  31. SRH         EQU    0        ;STATIC REQUEST HEADER START
  32. SRH_LEN      EQU   13        ;  "      "       "    LENGTH
  33. SRH_LEN_FLD  EQU   SRH        ;  "      "       "      "    FIELD
  34. SRH_UCD_FLD  EQU   SRH+1    ;  "      "       "    UNIT CODE FIELD
  35. SRH_CCD_FLD  EQU   SRH+2    ;  "      "       "    COMMAND CODE FIELD
  36. SRH_STA_FLD  EQU   SRH+3    ;  "      "       "    STATUS FIELD
  37. SRH_RES_FLD  EQU   SRH+5    ;  "      "       "    RESERVED AREA FIELD
  38. ;
  39. MD     EQU   SRH+SRH_LEN    ;MEDIA DESCRIPTOR BYTE
  40. MD_LEN     EQU   1        ;  "      "        "   LENGTH
  41. DTA     EQU   MD+MD_LEN    ;DISK TRANSFER ADDRESS
  42. DTA_LEN  EQU   4        ; DTA LENGTH
  43. COUNT     EQU   DTA+DTA_LEN    ;BYTE/SECTOR COUNT
  44. COUNT_LEN EQU  2        ; "     "      "    LENGTH
  45. SSN     EQU   COUNT+COUNT_LEN    ;STARTING SECTOR NUMBER
  46. SSN_LEN  EQU   2        ;   "       "      "     LENGTH
  47. ;
  48. ;  MEDIA CHECK
  49. ;
  50. RET_BYTE  EQU    MD+MD_LEN    ;BYTE RETURNED FROM DRIVER
  51. ;
  52. ; BUILD BPB
  53. ;
  54. BPBA_PTR     EQU  DTA+DTA_LEN    ;POINTER TO BPB
  55. BPBA_PTR_LEN EQU  4        ;   "     "  "  LENGTH
  56. ;
  57. ;  INIT
  58. ;
  59. UNITS        EQU   SRH+SRH_LEN
  60. UNITS_LEN   EQU   1
  61. BR_ADDR_0   EQU   UNITS+UNITS_LEN
  62. BR_ADDR_1   EQU   BR_ADDR_0+2
  63. BR_ADDR_LEN EQU   4
  64. BPB_PTR_OFF EQU   BR_ADDR_0+BR_ADDR_LEN
  65. BPB_PTR_SEG EQU   BPB_PTR_OFF+2
  66. ;
  67. ;
  68. VDSK     PROC    FAR
  69.      ASSUME CS:CSEG,ES:CSEG,DS:CSEG
  70. BEGIN:
  71. START        EQU    $
  72. ;    S P E C I A L  D E V I C E  H E A D E R
  73. NEXT_DEV    DD    -1        ;POINTER TO NEXT DEVICE
  74. ATTRIBUTE    DW    2000H        ;BLOCK DEVICE (NON-IBM FORMAT)
  75. STRATEGY    DW    DEV_STRATEGY    ;POINTER TO DEVICE STRATEGY
  76. INTERRUPT    DW    DEV_INT     ;POINTER TO DEVICE INTERRUPT HANDLER
  77. DEV_NAME    DB    1        ;NUMBER OF BLOCK DEVICES
  78.         DB    7 DUP (?)    ;7 BYTES OF FILLER
  79. ;
  80. RH_OFF        DW    ?        ;REQUEST HEADER OFFSET
  81. RH_SEG        DW    ?        ;REQUEST HEADER SEGMENT
  82. ;  BIOS PARAMETER BLOCK
  83. BPB        EQU    $
  84.         DW    512        ;SECTOR SIZE
  85.         DB    1        ;SECTOR/ALLOCATION UNIT
  86.         DW    1        ;NUMBER OF RESERVED SECTORS
  87.         DB    2        ;NUMBER OF FATS
  88.         DW    64        ;NUMBER OF DIRECTORY ENTRIES
  89.         DW    360        ;TOTAL NUMBER OF SECTORS
  90.         DB    0FCH        ;MEDIA DESCRIPTOR
  91.         DW    2        ;NUMBER OF SECTORS OCCUPIED BY FAT
  92. ;
  93. BPB_PTR     DW    BPB        ;BIOS PARAMETER BLOCK POINTER ARRAY (1 ENTR)
  94. ;  CURRENT VIRTUAL DISK INFORMATION
  95. TOTAL        DW    ?        ;TOTAL SECTORS TO TRANSFER
  96. VERIFY        DB    0        ;VERIFY 1=YES, 0=NO
  97. START_SEC    DW    0        ;STARTING SECTOR NUMBER
  98. VDISK_PTR    DW    0        ;STARTING SEGMENT OF VIRTUAL DISK
  99. USER_DTA    DD    ?        ;POINTER TO CALLSER DISK TRANSFER ADDRESS
  100. BOOT_REC    EQU    $        ;DUMMY DOS BOOT RECORD
  101.         DB    3 DUP (0)    ;3 BYTE JUMP TO BOOT CODE (NOT BOOTABLE)
  102.         DB    'IBM  2.0'      ;VENDOR IDENTIFICATION
  103.         DW    512        ;NUMBER OF BYTES IN A SECTOR
  104.         DB    1        ;1 SECTOR PER ALLOCATION UNIT
  105.         DW    1        ;1 RESERVED SECTOR
  106.         DB    2        ;2 FATS
  107.         DW    64        ;NUMBER OF DIRECTORY ENTRIES
  108.         DW    360        ;360 TOTAL SECTORS IN IMAGE
  109.         DB    0FCH        ;TELLS DOS THIS IS A SINGLE SIDED 9 SECTOR
  110.         DW    2        ;NUMBER OF SECTORS IN FAT
  111. ;
  112. ;    FUNCTION TABLE
  113. ;
  114. FUNTAB        LABEL    BYTE
  115.         DW    INIT        ;INITIALIZATION
  116.         DW    MEDIA_CHECK    ;MEDIA CHECK (BLOCK ONLY)
  117.         DW    BUILD_BPB    ;BUILD BPB    "     "
  118.         DW    IOCTL_IN    ;IOCTL INPUT
  119.         DW    INPUT        ;INPUT (READ)
  120.         DW    ND_INPUT    ;NON_DESTIUCTIVE INPUT NO WAIT (CHAR ONLY)
  121.         DW    IN_STAT     ;INPUT STATUS  (CHAR ONLY)
  122.         DW    IN_FLUSH ;INPUT FLUSH       "   "
  123.         DW    OUTPUT        ;OUTPUT (WRITE)
  124.         DW    OUT_VERIFY    ;OUTPUT (WRITE) WITH VERIFY
  125.         DW    OUT_STAT    ;OUTPUT STATUS    (CHAR ONLY)
  126.         DW    OUT_FLUSH    ;OUTPUT FLUSH      "   "
  127.         DW    IOCTL_OUT    ;IOCTL OUTPUT
  128. ;
  129. ;  L O C A L  P R O C E D U R E S
  130. ;
  131. IN_SAVE     PROC    NEAR
  132.         MOV    AX,ES:WORD PTR DTA[BX]     ;SAVE CALLERS DTA
  133.         MOV    CS:USER_DTA,AX
  134.         MOV    AX,ES:WORD PTR DTA+2[BX]
  135.         MOV    CS:USER_DTA+2,AX
  136.         MOV    AX,ES:WORD PTR COUNT[BX]  ;GET NUMBER OF SECTOR TO TOTAL
  137.         XOR    AH,AH
  138.         MOV    CS:TOTAL,AX          ;MOVE NUMBER OF SECTORS TO TOTAL
  139.         RET
  140. IN_SAVE     ENDP
  141. ;
  142. CALC_ADDR    PROC    NEAR
  143.         MOV    AX,CS:START_SEC ;GET STARTING SECTOR NUMBER
  144.         MOV    CX,20H        ;MOV 512 TO CX SEGMENT STYLE
  145.         MUL    CX        ;MULTIPLY TO GET ACTUAL SECTOR
  146.         MOV    DX,CS:VDISK_PTR ;GET SEGMENT OF VIRTUAL DISK
  147.         ADD    DX,AX        ;ADD THAT SEGMENT TO INITIAL SEGMENT
  148.         MOV    DS,DX        ;SAVE THAT AS THE ACTUAL SEGMENT
  149.         XOR    SI,SI        ;IT'S ON A PARAGRAPH BOUNDRY
  150.         MOV    AX,CS:TOTAL    ;TOTAL NUMBER OF SECTOR TO READ
  151.         MOV    CX,512        ;BYTES PER SECTOR
  152.         MUL    CX        ;MULTIPLY TO GET COPY LENGTH
  153.         OR    AX,AX        ;CHECK FOR GREATER THAN 64K
  154.         JNZ    MOVE_IT
  155.         MOV    AX,0FFFFH ;MOVE IN FOR 64K
  156. MOVE_IT:
  157.         XCHG    CX,AX        ;MOVE LENGTH TO CX
  158.         RET
  159. CALC_ADDR    ENDP
  160. ;
  161. SECTOR_READ    PROC    NEAR
  162.         CALL    CALC_ADDR ;CALCULATE THE STARTING 'SECTOR'
  163.         MOV    ES,CS:USER_DTA+2 ;SET DESTINATION (ES:DI) TO POINT
  164.         MOV    DI,CS:USER_DTA     ;TO CALLERS DTA
  165. ;
  166. ;  CHECK FOR DTA WRAP IN CASE WE CAME THROUGH VIA VERIFY
  167. ;
  168.         MOV    AX,DI        ;GET OFFSET OF DTA
  169.         ADD    AX,CX        ;ADD COPY LENGTH TO IT
  170.         JNC    READ_COPY ;CARRY FLAG = 0, NO WRAP
  171.         MOV    AX,0FFFFH    ;MAX LENGTH
  172.         SUB    AX,DI        ;SUBTRACT DTA OFFSET FROM MAX
  173.         MOV    CX,AX        ;USE THAT AS COPY LENGTH TO AVOID WRAP
  174. READ_COPY:
  175. REP        MOVSB            ;DO THE 'READ'
  176.         RET
  177. SECTOR_READ    ENDP
  178. ;
  179. SECTOR_WRITE PROC    NEAR
  180.         CALL    CALC_ADDR ;CALCULATE STARTING 'SECTOR'
  181.         PUSH    DS
  182.         POP    ES        ;ESTABLISH ADDRESSABILITY
  183.         MOV    DI,SI        ; ES:DI POINT TO 'DISK`
  184.         MOV    DS,CS:USER_DTA+2 ; DS:SI POINT TO CALLERS DTA
  185.         MOV    SI,CS:USER_DTA
  186. ;
  187. ; CHECK FOR DTA WRAP
  188. ;
  189.         MOV    AX,SI        ;MOVE DTA OFFSET TO AX
  190.         ADD    AX,CX        ;ADD COPY LENGTH TO OFFSET
  191.         JNC    WRITE_COPY    ;CARRY FLAG = 0, NO SEGMENT WRAP
  192.         MOV    AX,0FFFFH    ;MOVE IN MAX COPY LENGTH
  193.         SUB    AX,SI        ;SUTRACT DTA OFFSET FROM MAX
  194.         MOV    CX,AX        ;USE AS NEW COPY LENGTH TO AVOID WRAP
  195. WRITE_COPY:
  196. REP        MOVSB            ;DO THE 'WRITE'
  197.         RET
  198. SECTOR_WRITE    ENDP
  199. ;
  200. ;  D E V I C E    S T R A T E G Y
  201. ;
  202. DEV_STRATEGY:
  203.         MOV    CS:RH_SEG,ES    ;SAVE SEGMENT OF REQUEST HEADER POINTER
  204.         MOV    CS:RH_OFF,BX    ;SAVE OFFSET OF   "       "...
  205.         RET
  206. ;
  207. ;  D E V I C E    I N T E R R U P T  H A N D L E R
  208. ;
  209. DEV_INT:
  210. ;  PRESERVE MACHINE STATE ON ENTRY
  211.         CLD
  212.         PUSH    DS
  213.         PUSH    ES
  214.         PUSH    AX
  215.         PUSH    BX
  216.         PUSH    CX
  217.         PUSH    DX
  218.         PUSH    DI
  219.         PUSH    SI
  220. ;
  221. ;  DO THE BRANCH ACCORDING TO THE FUNCTION PASSED
  222. ;
  223.         MOV    AL,ES:[BX]+2    ;GET FUNCTION BYTE
  224.         ROL    AL,1        ;GET OFFSET INTO TABLE
  225.         LEA    DI,FUNTAB    ;GET ADDRESS OF FUNCTION TABLE
  226.         XOR    AH,AH
  227.         ADD    DI,AX
  228.         JMP    WORD PTR[DI]
  229. ;
  230. ;   INIT
  231. ;
  232. INIT:
  233.         PUSH    CS
  234.         POP    DX        ;CURRENT CS TO DX
  235.         LEA    AX,CS:VDISK    ;GET ADDRESS OF VIRTUAL DISK
  236.         MOV    CL,4
  237.         ROR    AX,CL        ;DIVIDE BY 15 (PARAGRAPH FORM)
  238.         ADD    DX,AX        ;ADD TO CURRENT CS VALUE
  239.         MOV    CS:VDISK_PTR,DX ;SAVE AS STARTING SEGMENT OF VIRTUAL DISK
  240.         MOV    AX,2D00H    ; ADD 2D00H PARAGRAPH TO STARTING
  241.         ADD    DX,AX        ;    SEGMENT OF VIRTUAL DISK
  242.         MOV    ES:WORD PTR BR_ADDR_0[BX],0
  243.         MOV    ES:BR_ADDR_1[BX],DX     ;MAKE THAT THE BREAK ADDRESS
  244.         MOV    ES:BYTE PTR UNITS[BX],1  ;NUMBER OF DISKETTE UNITS
  245.         LEA    DX,BPB_PTR           ;GET ADDRESS OF BPB POINTER ARRAY
  246.         MOV    ES:BPB_PTR_OFF[BX],DX  ;SAVE OFFSET IN DATA PACKET
  247.         MOV    ES:BPB_PTR_SEG[BX],CS  ;SAVE SEGMENT IN DATA PACKET
  248.         MOV    ES,CS:VDISK_PTR        ;GET STARTING SECTOR OF VIRTUAL DISK
  249.         XOR    DI,DI               ;ZERO OUT DI (BOOT RECORD)
  250.         LEA    SI,BOOT_REC           ;ADDRESS OF BOOT RECORD
  251.         MOV    CX,24
  252. REP        MOVSB                   ;COPY 24 BYTES OF BOOT RECORD
  253.         MOV    CS:WORD PTR START_SEC,1
  254.         MOV    CS:WORD PTR TOTAL,2
  255.         CALL    CALC_ADDR    ;CALCULATE ADDRESS OF LOGICAL SECTOR 1
  256.         PUSH    DS
  257.         POP    ES
  258.         MOV    DI,SI        ;MOVE THAT ADDRES TO ES:DI
  259.         XOR    AL,AL
  260. REP        STOSB                ;ZERO OUT FAT AREA
  261.         MOV    DS:BYTE PTR [SI],0FCH    ;SET THE FIRST FAT ENTRY
  262.         MOV    DS:BYTE PTR 1[SI],0FFH
  263.         MOV    DS:BYTE PTR 2[SI],0FFH
  264.         PUSH    DS            ;SAVE POINTER TO FAT
  265.         PUSH    SI            ;       ON THE STACK
  266.         MOV    CS:WORD PTR START_SEC,3
  267.         MOV    CS:WORD PTR TOTAL,2
  268.         CALL    CALC_ADDR        ;CALCULATE ADDRESS OF LOGICAL SECTOR 3
  269.         PUSH    DS
  270.         POP    ES
  271.         MOV    DI,SI            ;MOVE THAT ADDRESS TO ES:DI
  272.         POP    SI
  273.         POP    DS            ;RESTORE ADDRESS TO FIRST FAT
  274. REP        MOVSB            ;COPY FIRST FAT TO SECOND FAT
  275.         MOV    CS:WORD PTR START_SEC,5
  276.         MOV    CS:WORD PTR TOTAL,4
  277.         CALL    CALC_ADDR        ;CALCULATE ADDR OF L.S. 5 (START OF DIR)
  278.         XOR    AL,AL
  279.         PUSH    DS
  280.         POP    ES            ;SET UP ES:DI TO POINT T
  281.         XOR    DI,DI
  282. REP        STOSB                ;ZERO OUT DIRECTORY
  283.         MOV    ES,CS:RH_SEG        ;RESTORE ES:BX TO REQUEST HEADER
  284.         MOV    BX,CS:RH_OFF
  285.         STATUS    DONE,NOERROR,0        ;SET STATUS WORD (DONE, NOERROR)
  286.         JMP    EXIT
  287. ;
  288. ;  MEDIA CHECK
  289. ;
  290. MEDIA_CHECK:                    ;MEDIA CHECK (BLOCK ONLY)
  291. ;
  292. ;  SET MEDIA NOT CHANGED
  293. ;
  294.         MOV    ES:BYTE PTR RET_BYTE[BX],1  ;STORE IN RETURN BYTE
  295.         STATUS    DONE,NOERROR,0
  296.         JMP    EXIT
  297. ;
  298. ;  BUILD BIOS PARAMETER BLOCK
  299. ;
  300. BUILD_BPB:
  301.         PUSH    ES        ;SAVE SRH SEGMENT
  302.         PUSH    BX        ;SAVE SRH OFFSET
  303.         MOV    CS:WORD PTR START_SEC,0
  304.         MOV    CS:WORD PTR TOTAL,1
  305.         CALL    CALC_ADDR
  306.         PUSH    CS
  307.         POP    ES
  308.         LEA    DI,BPB        ;ADDRESS OF BIOS PARAMETER BLOCK
  309.         ADD    SI,11        ;ADD 11 TO SI
  310.         MOV    CX,13        ;LENGTH OF BPB
  311. REP        MOVSB
  312.         POP    BX        ;RESTORE OFFSET OF SRH
  313.         POP    ES        ;RESTORE SEGMENT OF SRH
  314.         LEA    DX,BPB        ;GET BPB ARRAY POINTER
  315.         MOV    ES:BPBA_PTR[BX],DX  ;SAVE PTR TO BPB TABLE
  316.         MOV    ES:BPBA_PTR+2[BX],CS
  317.         MOV    ES:DTA[BX],DX ;OFFSET OF SECTOR BUFFER
  318.         MOV    ES:DTA+2[BX],CS
  319.         STATUS    DONE,NOERROR,0
  320.         JMP    EXIT
  321. ;
  322. ;  THE FOLLOWING ENTRIES ARE FOR NOT SUPPORTED BY THIS DEVICE
  323. ;
  324. IOCTL_IN:
  325. IOCTL_OUT:
  326. ND_INPUT:            ;NON_DESTRUCTIVE INPUT NO WAIT (CHAR ONLY)
  327. IN_STAT:            ;INPUT STATUS "    "....
  328. IN_FLUSH:            ;INPUT FLUSH  "    "....
  329. OUT_STAT:            ;OUTPUT STATUS"    "....
  330. OUT_FLUSH:            ;OUTPUT FLUSH "    "....
  331. ;
  332. ;  DISK READ
  333. ;
  334. INPUT:
  335.         CALL    IN_SAVE     ;CALL THE INITIAL SAVE ROUTINE
  336.         MOV    AX,ES:WORD PTR SSN[BX]    ;SET STARTING SECTOR NUMBER
  337.         MOV    CS:START_SEC,AX     ;SAVE STARTING SECTOR NUMBER
  338.         MOV    AX,ES:WORD PTR COUNT[BX]
  339.         MOV    CS:TOTAL,AX        ;SAVE TOTAL SECTORS TO TRANSFER
  340.         CALL    SECTOR_READ        ;READ IN THAT MANY SECTORS
  341.         MOV    BX,CS:RH_OFF        ;RESTORE ES:BX AS REQUEST HEADER POINTER
  342.         MOV    ES,CS:RH_SEG
  343.         STATUS    DONE,NOERROR,0
  344.         JMP    EXIT
  345. ;
  346. ;  DISK WRITE
  347. ;
  348. OUTPUT:                     ;OUTPUT (WRITE)
  349.         CALL    IN_SAVE
  350.         MOV    AX,ES:WORD PTR SSN[BX]    ;GET STARTING SECTOR NUMBER
  351.         MOV    CS:START_SEC,AX     ;SET "        "......
  352.         MOV    AX,ES:WORD PTR COUNT[BX]
  353.         MOV    CS:TOTAL,AX        ;SAVE TOTAL SECTORS TO WRITE
  354.         CALL    SECTOR_WRITE        ;WRITE OUT THOSE SECTORS
  355.         MOV    BX,CS:RH_OFF        ;RESTORE ES:BX AS REQUEST HEADER POINTER
  356.         MOV    ES,CS:RH_SEG
  357.         CMP    CS:BYTE PTR VERIFY,0    ;WRITE VERIFY SET
  358.         JZ NO_VERIFY        ;NO, NO WRITE VERIFY
  359.         MOV    CS:BYTE PTR VERIFY,0    ;RESET VERIFY INDICATOR
  360.         JMP    INPUT            ;READ THOSE SECTORS BACK IN
  361. NO_VERIFY:
  362.         STATUS    DONE,NOERROR,0        ;SET DONE, NO EROR IN STATUS WORD
  363.         JMP    EXIT
  364. OUT_VERIFY:                    ;OUTPUT (WRITE) WITH VERIFY
  365.         MOV    CS:BYTE PTR VERIFY,1    ;SET THE VERIFY FLAG
  366.         JMP    OUTPUT            ;BRANCH TO OUTPUT ROUTINE
  367. ;
  368. ;  COMMON EXIT
  369. ;
  370. EXIT:
  371.         POP    SI        ;RESTORE ALL REGISTERS
  372.         POP    DI
  373.         POP    DX
  374.         POP    CX
  375.         POP    BX
  376.         POP    AX
  377.         POP    ES
  378.         POP    DS
  379.         RET
  380. E_O_P:
  381. ; ALIGN VIRTUAL DISK ON A PARAGRAPH
  382. IF ($-START) MOD 16
  383. ORG    ($-START)+16-(($-START) MOD 16)
  384. ENDIF
  385. VDISK        EQU    $
  386. VDSK        ENDP
  387. CSEG        ENDS
  388.         END    BEGIN
  389.